﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
namespace Com.Alipay
{
    public class AlipayHandle
    {
        /// <summary>
        /// 支付宝支付
        /// </summary>
        /// <param name="outTradeNo">订单编号</param>
        /// <param name="subject">订单名称</param>
        /// <param name="totalFee">付款金额</param>
        /// <param name="body">订单描述</param>
        /// <param name="showUrl">商品展示地址</param>
        /// <returns></returns>
        public string GoAlipay(string outTradeNo, string subject, string totalFee, string body = "", string showUrl = "")
        {
            ////////////////////////////////////////////请求参数////////////////////////////////////////////

            //支付类型
            const string paymentType = "1";
            //必填，不能修改
            //服务器异步通知页面路径
            string notifyUrl = Config.Notify_url;
            //需http://格式的完整路径，不能加?id=123这类自定义参数

            //页面跳转同步通知页面路径
            string returnUrl = Config.Return_url;
            //需http://格式的完整路径，不能加?id=123这类自定义参数，不能写成http://localhost/

            //卖家支付宝帐户
            string sellerEmail = Config.AlipayAccount;
            //必填
            //
            //            //商户订单号
            //            string out_trade_no = orderID;
            //            //商户网站订单系统中唯一订单号，必填
            //
            //            //订单名称
            //            string subject = name;
            //            //必填
            //
            //            //付款金额
            //            string total_fee = money;
            //            //必填
            //
            //            //订单描述       
            //
            //            string body = des;
            //            //商品展示地址
            //            string show_url = "http://www.baidu.com";
            //            //需以http://开头的完整路径，例如：http://www.xxx.com/myorder.html

            //防钓鱼时间戳
            string antiPhishingKey = Submit.Query_timestamp();
            //若要使用请调用类文件submit中的query_timestamp函数

            //客户端的IP地址
            string exterInvokeIp = Config.RequestIP;
            //非局域网的外网IP地址，如：221.0.0.1


            ////////////////////////////////////////////////////////////////////////////////////////////////

            //把请求参数打包成数组
            var sParaTemp = new SortedDictionary<string, string>
                {
                    {"partner", Config.Partner},
                    {"_input_charset", Config.Input_charset.ToLower()},
                    {"service", "create_direct_pay_by_user"},
                    {"payment_type", paymentType},
                    {"notify_url", notifyUrl},
                    {"return_url", returnUrl},
                    {"seller_email", sellerEmail},
                    {"out_trade_no", outTradeNo},
                    {"subject", subject},
                    {"total_fee", totalFee},
                    {"body", body},
                    {"show_url", showUrl},
                    {"anti_phishing_key", antiPhishingKey},
                    {"exter_invoke_ip", exterInvokeIp}
                };

            //建立请求
            string sHtmlText = Submit.BuildRequest(sParaTemp, "get", "确认");
            return sHtmlText;
        }

        /// <summary>
        /// 通知处理
        /// </summary>
        /// <returns></returns>
        private string NotifyView(HttpRequest request)
        {
            var back = "";
            SortedDictionary<string, string> sPara = GetRequestPost(request);

            if (sPara.Count > 0)//判断是否有带返回参数
            {
                Notify aliNotify = new Notify();
                bool verifyResult = aliNotify.Verify(sPara, request.Form["notify_id"], request.Form["sign"]);

                if (verifyResult)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码


                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表

                    //商户订单号

                    string out_trade_no = request.Form["out_trade_no"];

                    //支付宝交易号

                    string trade_no = request.Form["trade_no"];

                    //交易状态
                    string trade_status = request.Form["trade_status"];


                    if (request.Form["trade_status"] == "TRADE_FINISHED")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序

                        //注意：
                        //该种交易状态只在两种情况下出现
                        //1、开通了普通即时到账，买家付款成功后。
                        //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
                    }
                    else if (request.Form["trade_status"] == "TRADE_SUCCESS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序

                        //注意：
                        //该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。
                    }
                    else
                    {
                    }

                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

                    back = "success";  //请不要修改或删除

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else//验证失败
                {
                    back = "fail";
                }
            }
            else
            {
                back = "无通知参数";
            }
            return back;
        }


        /// <summary>
        /// 返回处理
        /// </summary>
        private string ReturnView(HttpRequest request)
        {
            var back = "";
            SortedDictionary<string, string> sPara = GetRequestGet(request);

            if (sPara.Count > 0)//判断是否有带返回参数
            {
                Notify aliNotify = new Notify();
                bool verifyResult = aliNotify.Verify(sPara, request.QueryString["notify_id"], request.QueryString["sign"]);

                if (verifyResult)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码


                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表

                    //商户订单号

                    string out_trade_no = request.QueryString["out_trade_no"];

                    //支付宝交易号

                    string trade_no = request.QueryString["trade_no"];

                    //交易状态
                    string trade_status = request.QueryString["trade_status"];


                    if (request.QueryString["trade_status"] == "TRADE_FINISHED" || request.QueryString["trade_status"] == "TRADE_SUCCESS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                    }
                    else
                    {
                        back = "trade_status=" + request.QueryString["trade_status"];
                    }

                    //打印页面
                    back = "验证成功<br />";

                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else//验证失败
                {
                    back = "验证失败";
                }
            }
            else
            {
                back = "无返回参数";
            }
            return back;
        }

        /// <summary>
        /// 【通知】获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        private SortedDictionary<string, string> GetRequestPost(HttpRequest request)
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], request.Form[requestItem[i]]);
            }

            return sArray;
        }

        /// <summary>
        /// 【返回】获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        private SortedDictionary<string, string> GetRequestGet(HttpRequest request)
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], request.QueryString[requestItem[i]]);
            }

            return sArray;
        }
    }
}
